package com.shop.loan.aop;

import com.alibaba.fastjson.JSONObject;
import com.shop.loan.model.common.Code;
import com.shop.loan.model.common.Constant;
import com.shop.loan.model.common.RequestBase;
import com.shop.loan.model.common.ResResult;
import com.shop.loan.util.BlackUtil;
import com.shop.loan.util.Util;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import xyz.erupt.core.exception.EruptApiErrorTip;
import xyz.erupt.core.view.EruptApiModel;
import xyz.erupt.upms.util.IpUtil;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

@Slf4j
@Component
@Aspect
@Order(1)
public class RequestLogAspect {

    @Resource
    BlackUtil blackUtil;

    @Resource
    Util util;

    @Pointcut("execution(* com.shop.loan.controller.*.*(..))")
    private void controllerAop() {
    }

    @Around("controllerAop()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest httpServletRequest = attributes.getRequest();
        String requestPath = httpServletRequest.getServletPath();

        long startTime = System.currentTimeMillis();
        JSONObject paramJs = util.logParam(requestPath, httpServletRequest, startTime);

        //校验参数是否存在js脚本
        if (Util.checkContent(requestPath,paramJs.toJSONString())) {
            return new ResResult(Code.PARAM_REJECT);
        }

        if (blackUtil.checkIsBlacklist(httpServletRequest)) {
            throw new EruptApiErrorTip("ip存在异常，请联系管理员", EruptApiModel.PromptWay.MESSAGE);
        }

        if (!blackUtil.checkIpRegion(httpServletRequest)) {
            throw new EruptApiErrorTip("ip地区异常", EruptApiModel.PromptWay.MESSAGE);
        }

        Object[] obj = joinPoint.getArgs();
        for (Object argItem : obj) {
            if (argItem != null && argItem instanceof RequestBase) {
                RequestBase requestBase = (RequestBase) argItem;
                /**
                 * 将常用参数存储到请求基类中
                 */
                requestBase.setOpIp(IpUtil.getIpAddr(httpServletRequest));
                if (StringUtils.hasLength(httpServletRequest.getHeader(Constant.pFrom))) {
                    requestBase.setPFrom(httpServletRequest.getHeader(Constant.pFrom));
                }
            }
        }
        return joinPoint.proceed();
    }

    @AfterReturning(returning = "result", pointcut = "controllerAop()")
    public void AfterReturning(Object result) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        Long startTime = (Long) request.getAttribute(Constant.ATTRIBUTES_TIME_KEY);
        if (startTime != null) {
            Long executeTime = (System.currentTimeMillis() - startTime);
            if (!request.getServletPath().contains("home/get") && !request.getServletPath().contains("goods/detail")) {
                log.info("请求:{} 结束---,耗时:{} 毫秒,返回结果:{}，时间标识:{}", request.getServletPath(), executeTime, result != null ? result.toString() : null, startTime);
            } else {
                log.info("请求:{} 结束---,耗时:{} 毫秒,时间标识:{}", request.getServletPath(), executeTime, startTime);
            }
        }
    }


}
